package com.wind.gtest.GMapItemManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import android.graphics.Color;
import android.location.Location;
import android.opengl.Visibility;
import android.util.Log;
import android.util.SparseArray;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.wind.data.BlockData;
import com.wind.gtest.GTApplication;
import com.wind.gtest.R;
import com.wind.gtest.bean.LatBean;
import com.wind.gtest.bean.SqlDataBean;

public class GMapSharpManager {
	private final String TAG = "GMapSharpManager";
	private static GMapSharpManager instance = null;

	GMapSharpManager() {
		// TODO Auto-generated constructor stub
	}

	public static GMapSharpManager getInstance() {
		if (instance == null) {
			instance = new GMapSharpManager();
		}
		return instance;
	}

	public void addPolyline(GoogleMap map, Location location) {
		// Instantiates a new Polyline object and adds points to define a
		// rectangle
		PolylineOptions rectOptions = new PolylineOptions()
		// .add(new LatLng(37.35, -122.0))
		// .add(new LatLng(37.45, -122.0)) // North of the previous
		// point, but at the same longitude
		// .add(new LatLng(37.45, -122.2)) // Same latitude, and 30km to
		// the west
		// .add(new LatLng(37.35, -122.2)) // Same longitude, and 16km
		// to the south
		// .add(new LatLng(37.35, -122.0)); // Closes the polyline.
				.add(new LatLng(location.getLatitude(), location.getLongitude()))
				.add(new LatLng(location.getLatitude() + 0.1, location
						.getLongitude())) // North of the previous point,
				// but at the same longitude
				.add(new LatLng(location.getLatitude() + 0.1, location
						.getLongitude() - 0.2)) // Same latitude, and 30km to
				// the west
				.add(new LatLng(location.getLatitude(),
						location.getLongitude() - 0.2)) // Same longitude, and
														// 16km to
				// the south
				.add(new LatLng(location.getLatitude(), location.getLongitude())); // Closes
		// the
		// polyline.

		// Get back the mutable Polyline
		Polyline polyline = map.addPolyline(rectOptions);
		// Polyline.setPoints()
	}

	/**
	 * test
	 * 
	 * @param map
	 */
	public void addPolyline(GoogleMap map) {
		// Instantiates a new Polyline object and adds points to define a
		// rectangle

		PolylineOptions rectOptions = new PolylineOptions();
		for (int i = 0; i < BlockData.region1.length; i++) {
			String array_element = BlockData.region1[i];
			String[] lat = array_element.split(" ");
			rectOptions.add(new LatLng(Double.parseDouble(lat[1]), Double
					.parseDouble(lat[0])));
		}
		rectOptions.width(1f);
		rectOptions.color(Color.BLUE);
		// .add(new LatLng(location.getLatitude(), location.getLongitude()))
		// .add(new LatLng(location.getLatitude() + 0.1, location
		// .getLongitude())) // North of the previous point,
		// // but at the same longitude
		// .add(new LatLng(location.getLatitude() + 0.1, location
		// .getLongitude() - 0.2)) // Same latitude, and 30km to
		// // the west
		// .add(new LatLng(location.getLatitude(),
		// location.getLongitude() - 0.2)) // Same longitude, and
		// // 16km to
		// // the south
		// .add(new LatLng(location.getLatitude(), location.getLongitude())); //
		// Closes
		// the
		// polyline.

		// Get back the mutable Polyline
		Polyline polyline = map.addPolyline(rectOptions);
		// Polyline.setPoints()
	}

	/**
	 * test
	 * 
	 * @param map
	 */
	public void addSqlDataBean(GoogleMap map, SqlDataBean bean) {
		// Instantiates a new Polyline object and adds points to define a
		// rectangle
		lines = new SparseArray<Polyline>();
		int region = bean.getRegion();
		ArrayList<LatBean> lats = bean.getLats();
		PolylineOptions rectOptions = new PolylineOptions();

		for (int i = 0; i < lats.size(); i++) {
			rectOptions.add(new LatLng(lats.get(i).getLatitude(), lats.get(i)
					.getLongitude()));
		}
		// for (LatBean latBean : lats) {
		// rectOptions.add(new LatLng(latBean.getLatitude(), latBean
		// .getLongitude()));
		// }
		// for (int i = 0; i < BlockData.region1.length; i++) {
		// String array_element = BlockData.region1[i];
		// String[] lat = array_element.split(" ");
		//
		// }
		rectOptions.width(1f);
		rectOptions.color(Color.BLUE);
		// .add(new LatLng(location.getLatitude(), location.getLongitude()))
		// .add(new LatLng(location.getLatitude() + 0.1, location
		// .getLongitude())) // North of the previous point,
		// // but at the same longitude
		// .add(new LatLng(location.getLatitude() + 0.1, location
		// .getLongitude() - 0.2)) // Same latitude, and 30km to
		// // the west
		// .add(new LatLng(location.getLatitude(),
		// location.getLongitude() - 0.2)) // Same longitude, and
		// // 16km to
		// // the south
		// .add(new LatLng(location.getLatitude(), location.getLongitude())); //
		// Closes
		// the
		// polyline.

		// Get back the mutable Polyline
		Polyline polyline = map.addPolyline(rectOptions);
		lines.put(region, polyline);
		LatBean center = bean.getCenter();
		// 添加中心点
		Marker marker = map
				.addMarker(new MarkerOptions()
						.position(
								new LatLng(center.getLatitude(), center
										.getLongitude()))
						.title("addpos")
						.snippet(
								"Region=" + bean.getRegion() + "Number="
										+ bean.getNumber())
						.icon(BitmapDescriptorFactory
								.fromResource(R.drawable.star)));
		markers.put(region, marker);
		// map.setOnInfoWindowClickListener(new
		// GMapMarkerInfoClick(GTApplication
		// .getInstance()));
		// map.setOnMarkerClickListener(new GMapMarkerClick(GTApplication
		// .getInstance()));
		// map.setInfoWindowAdapter(new GMapMarkerInfoAdapter());
		// Polyline.setPoints()
	}

	SparseArray<Polyline> lines = new SparseArray<Polyline>();
	SparseArray<Marker> markers = new SparseArray<Marker>();

	/**
	 * test
	 * 
	 * @param map
	 */
	public void addSqlDataBeanArray(GoogleMap map,
			ArrayList<SqlDataBean> beanArray) {
		// Instantiates a new Polyline object and adds points to define a
		// rectangle
		// ArrayList<Polyline> lines = new ArrayList<Polyline>();
		// ArrayList<Marker> markers = new ArrayList<Marker>();
		lines = new SparseArray<Polyline>();
		for (SqlDataBean bean : beanArray) {
			ArrayList<LatBean> lats = bean.getLats();
			PolylineOptions rectOptions = new PolylineOptions();
			for (int i = 0; i < lats.size(); i++) {
				rectOptions.add(new LatLng(lats.get(i).getLatitude(), lats.get(
						i).getLongitude()));
			}
			rectOptions.width(1f);
			rectOptions.color(Color.GRAY);
			// .add(new LatLng(location.getLatitude(),
			// location.getLongitude()))
			// .add(new LatLng(location.getLatitude() + 0.1, location
			// .getLongitude())) // North of the previous point,
			// // but at the same longitude
			// .add(new LatLng(location.getLatitude() + 0.1, location
			// .getLongitude() - 0.2)) // Same latitude, and 30km to
			// // the west
			// .add(new LatLng(location.getLatitude(),
			// location.getLongitude() - 0.2)) // Same longitude, and
			// // 16km to
			// // the south
			// .add(new LatLng(location.getLatitude(),
			// location.getLongitude())); //
			// Closes
			// the
			// polyline.
			int region = bean.getRegion();
			// Get back the mutable Polyline
			Polyline polyline = map.addPolyline(rectOptions);
			lines.put(region, polyline);
			// LatBean center = bean.getCenter();
			//
			// // 添加中心点
			// Marker marker = map
			// .addMarker(new MarkerOptions()
			// .position(
			// new LatLng(center.getLatitude(), center
			// .getLongitude()))
			// .title("addpos")
			// .snippet("Region=" + bean.getRegion())
			// .icon(BitmapDescriptorFactory
			// .fromResource(R.drawable.star)));
			// markers.put(region, marker);

			// map.setOnInfoWindowClickListener(new GMapMarkerInfoClick(
			// GTApplication.getInstance()));
			// map.setOnMarkerClickListener(new
			// GMapMarkerClick(GTApplication
			// .getInstance()));
			// map.setInfoWindowAdapter(new GMapMarkerInfoAdapter());
			// Polyline.setPoints()
		}
	}

	/**
	 * 显示输入的beanArray中部分的bean
	 * 
	 * @param map
	 */
	public void addSqlDataBeanArrayPart(GoogleMap map,
			ArrayList<SqlDataBean> beanArray) {
		lines = new SparseArray<Polyline>();
		for (SqlDataBean bean : beanArray) {
			int region = bean.getRegion();
			if (String.valueOf(region).startsWith("1")) {
				ArrayList<LatBean> lats = bean.getLats();
				PolylineOptions rectOptions = new PolylineOptions();
				for (int i = 0; i < lats.size(); i++) {
					rectOptions.add(new LatLng(lats.get(i).getLatitude(), lats
							.get(i).getLongitude()));
				}
				rectOptions.width(1f);
				rectOptions.color(Color.GRAY);
				// Get back the mutable Polyline
				Polyline polyline = map.addPolyline(rectOptions);
				lines.put(region, polyline);
				// LatBean center = bean.getCenter();
				// // 添加中心点
				// Marker marker = map
				// .addMarker(new MarkerOptions()
				// .position(
				// new LatLng(center.getLatitude(), center
				// .getLongitude()))
				// .title("addpos")
				// .snippet("Region=" + bean.getRegion())
				// .icon(BitmapDescriptorFactory
				// .fromResource(R.drawable.star)));
				// markers.put(region, marker);
			}
		}
		Log.d(TAG, "lines.size()=" + lines.size());
	}

	public void hideBeanArray() {
		if (lines != null) {
			for (int i = 0; i < lines.size(); i++) {
				lines.get(lines.keyAt(i)).setVisible(false);
			}
		}
	}

	public void showBeanArray() {
		for (int i = 0; i < lines.size(); i++) {
			lines.get(lines.keyAt(i)).setVisible(true);
		}
	}

	public void addCircle(GoogleMap map, Location location) {
		// Instantiates a new CircleOptions object and defines the center and
		// radius
		CircleOptions circleOptions = new CircleOptions().center(
				new LatLng(location.getLatitude(), location.getLongitude()))
				.radius(10000); // In meters

		// Get back the mutable Circle
		Circle circle = map.addCircle(circleOptions);
	}

	public void addPolygons(GoogleMap map, Location location) {
		Hole hole = new Hole();
		hole.add(new LatLng(location.getLatitude() - 0.025, location
				.getLongitude() + 0.05));
		hole.add(new LatLng(location.getLatitude() + 0.025, location
				.getLongitude()));
		hole.add(new LatLng(location.getLatitude() + 0.025, location
				.getLongitude() - 0.05));
		PolygonOptions rectOptions = new PolygonOptions()
				.add(new LatLng(location.getLatitude() - 0.05, location
						.getLongitude() + 0.1))
				.add(new LatLng(location.getLatitude() + 0.05, location
						.getLongitude()))
				// North of the previous point,
				.add(new LatLng(location.getLatitude() + 0.05, location
						.getLongitude() - 0.1))
				// Same latitude, and 30km to
				.add(new LatLng(location.getLatitude(),
						location.getLongitude() - 0.1)).addHole(hole)
				.geodesic(true).strokeColor(Color.RED).strokeWidth(1f)
				.fillColor(Color.BLUE); // Closes
		// Get back the mutable Polygon
		Polygon polygon = map.addPolygon(rectOptions);
	}

	public class Hole implements Iterable<LatLng> {

		List<LatLng> staffList = new ArrayList<LatLng>();

		public void add(LatLng staff) {
			this.staffList.add(staff);
		}

		public List<LatLng> getStaffList() {
			return staffList;
		}

		public Iterator<LatLng> iterator() {
			Itr itr = new Itr();
			itr.setDept(this);
			return itr;
		}
	}

	class Itr implements Iterator<LatLng> {

		private int cursor = -1;
		private Hole dept;

		public void setDept(Hole dept) {
			this.dept = dept;
		}

		public boolean hasNext() {
			return dept.getStaffList() != null
					&& dept.getStaffList().size() > cursor + 1;
		}

		public LatLng next() {
			return dept.getStaffList().get(++cursor);
		}

		public void remove() {
			dept.getStaffList().remove(cursor);
		}
	}

}
